/*******************************************************************************************
This file is part of iToday.

iToday is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

iToday is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with iToday.  If not, see <http://www.gnu.org/licenses/>.
* ------------------------------------------------------------------------------
*    HomePanel.cpp - Class HomePanel implement
* ------------------------------------------------------------------------------
*    Revision History
*    Date                  Author         Activity ID               Activity Headline
*    2009-10-13            Congqin				none						initial
*******************************************************************************************/

#include "stdafx.h"
#include "HomePanel.h"
#include "LogUtility.h"
//static HPHYSICSENGINE g_hPhysicsEngine = NULL;

HREGNOTIFY g_hRegNotify[ NOTI_NUM ] ;


void HomePanel::RegisterForPhoneNotifications()
{
    NOTIFICATIONCONDITION nc;
    nc.ctComparisonType = REG_CT_ANYCHANGE;
    nc.dwMask           = -1;
    nc.TargetValue.dw   = 0;

    BOOL bRegistSucess = FALSE;

    //regist missed call
    ERR_ON_FAIL( RegistryNotifyWindow ( SN_PHONEMISSEDCALLS_ROOT,
                                        SN_PHONEMISSEDCALLS_PATH,
                                        SN_PHONEMISSEDCALLS_VALUE,
										g_hWnd,
                                        WM_MISSEDEVENT,
                                        MISSEDCALL_EVENT,
                                        &nc,
                                        &g_hRegNotify[MISSEDCALL_EVENT]
                                      )
               );

    //regist unread sms
    ERR_ON_FAIL( RegistryNotifyWindow (SN_MESSAGINGSMSUNREAD_ROOT,
                                       SN_MESSAGINGSMSUNREAD_PATH,
                                       SN_MESSAGINGSMSUNREAD_VALUE,
                                       g_hWnd,
                                       WM_MISSEDEVENT,
                                       MISSEDSMS_EVENT,
                                       &nc,
                                       &g_hRegNotify[MISSEDSMS_EVENT]
                                      )
               );

    //regist unread email
    ERR_ON_FAIL( RegistryNotifyWindow (SN_MESSAGINGTOTALEMAILUNREAD_ROOT,
                                       SN_MESSAGINGTOTALEMAILUNREAD_PATH,
                                       SN_MESSAGINGTOTALEMAILUNREAD_VALUE,
                                       g_hWnd,
                                       WM_MISSEDEVENT,
                                       MISSEDEMAIL_EVENT,
                                       &nc,
                                       &g_hRegNotify[MISSEDEMAIL_EVENT]
                                      )
               );

    bRegistSucess = TRUE;

_ErrorLabel:
    if (!bRegistSucess)
        Logger::Instance().Log( LOG_TRACE, L"HomePanel::RegisterForPhoneNotifications: RegistryNotifyWindow is Failure!\n");
}


HomePanel::HomePanel()
{
    RECT rc;
    EMPTYRECT(rc);

    m_hRegion.left		= m_rcScreen.left;
    m_hRegion.right		= m_rcScreen.right ;
    m_hRegion.top		= m_rcScreen.bottom /10 ;
    m_hRegion.bottom	= m_rcScreen.bottom * 3/ 10;

    SetTimer (g_hWnd, HOME_TIME_TIMER_ID, HOME_TIME_REFRESH_MS, NULL ) ;

}


BOOL HomePanel::InitMemoryDC( HDC hPublicMemoryDC)
{
    Logger::Instance().Log( LOG_TRACE, L"MainThread: Into HomePanel::InitMemoryDC( HDC hPublicMemoryDC  ) \n" );
    TCHAR* pTimeFile = RES_PATH("LS_TimeBG.png") ;

    m_hMemoryDC = CreateCompatibleDC( m_hRealDC );
    if ( NULL == m_hMemoryDC )
    {
        Logger::Instance().Log( LOG_TRACE, L"create the m_HomeMemDC is failure! " );
        return FALSE;
    }

    m_hMemoryBm = CreateCompatibleBitmap( m_hRealDC, m_rcScreen.right, m_rcScreen.bottom * 2 / 5 );
    if ( NULL == m_hMemoryBm )
    {
        Logger::Instance().Log( LOG_TRACE, L"create the m_HomeMemBm is failure! ! " );
        return FALSE;
    }

    SelectObject( m_hMemoryDC, m_hMemoryBm );

    RECT  rc = { m_rcScreen.left, m_rcScreen.top, m_rcScreen.right, m_rcScreen.bottom / 5};

    BitBlt( m_hMemoryDC, 0, 0, m_rcScreen.right, m_rcScreen.bottom / 5,
            hPublicMemoryDC, 0, m_rcScreen.bottom / 10,
            SRCCOPY
          );

    DrawImage( m_hMemoryDC , rc, pTimeFile );

    BitBlt( m_hMemoryDC, 0, m_rcScreen.bottom / 5,
            m_rcScreen.right, m_rcScreen.bottom / 5,
            m_hMemoryDC, 0, 0,
            SRCCOPY
          );

    rc.left		= m_hRegion.left + m_hRegion.right / 20;
    rc.top		= m_hRegion.top;
    rc.bottom	= m_hRegion.bottom;
    rc.right	= (rc.bottom - rc.top)/6 + rc.left;

    InitNotification( rc );

    return TRUE;
}

BOOL HomePanel::Draw()
{
    BitBlt( m_hPublicMemoryDC,
            0,
            m_rcScreen.bottom / 10 ,
            m_rcScreen.right,
            m_rcScreen.bottom / 5,
            m_hMemoryDC,
            0,
            m_rcScreen.bottom / 5,
            SRCCOPY
          );

    DrawTime();
    CheckMissedEvent();

    return TRUE;
}

HomePanel::~HomePanel()
{
	KillTimer( g_hWnd, HOME_TIME_TIMER_ID) ;
        
    DELETE_OBJ( m_hMemoryBm );
    DELETE_OBJ( m_hMemoryDC );
    CloseAllNotifications();

}

BOOL HomePanel::DrawTime()
{
    Logger::Instance().Log( LOG_TRACE, L"MainThread: into HomePanel::DrawTime() \n");

    m_cTimeManager.SetData ( m_hRegion );
    m_cTimeManager.DrawTime (  m_hMemoryDC ,m_hPublicMemoryDC );

    return TRUE;
}

BOOL HomePanel::DrawMouseDownMenu(POINT pt)
{
    for ( int i = 0; i < NOTI_NUM; i++ )
    {
        if ( PtInRect(& m_NotiRectList[i].m_rc, pt)
                && m_NotiRectList[i].m_bIsEmpty == TRUE )
        {
            m_CurPressedIcon = m_NotiRectList[i].m_NotiName;

            BitBlt(m_hPublicMemoryDC,
                   m_NotiRectList[i].m_rc.left,
                   m_NotiRectList[i].m_rc.top,
                   m_NotiRectList[i].m_rc.right - m_NotiRectList[i].m_rc.left,
                   m_NotiRectList[i].m_rc.bottom - m_NotiRectList[i].m_rc.top,
                   m_hMemoryDC,
                   m_NotiRectList[i].m_rc.left,
                   m_NotiRectList[i].m_rc.top + m_rcScreen.bottom / 10,
                   SRCCOPY
                  );

            AlphaBlt(m_hPublicMemoryDC,
                     m_NotiRectList[i].m_rc.left,
                     m_NotiRectList[i].m_rc.top,
                     m_NotiRectList[i].m_rc.right - m_NotiRectList[i].m_rc.left,
                     m_NotiRectList[i].m_rc.bottom - m_NotiRectList[i].m_rc.top,
                     m_hMemoryDC,
                     m_NotiRectList[i].m_rc.left,
                     m_NotiRectList[i].m_rc.top - m_rcScreen.bottom / 10 ,
                     m_NotiRectList[i].m_rc.right - m_NotiRectList[i].m_rc.left,
                     m_NotiRectList[i].m_rc.bottom - m_NotiRectList[i].m_rc.top,
                     150
                    );

            DrawMemDCToCurrentDC( m_hRealDC, m_hPublicMemoryDC, m_rcScreen );


            break;
        }
    }//end for

    return TRUE;
}


void HomePanel::InitNotification(RECT rc)
{
    TCHAR* szNotiPicture[] =
    {
        RES_PATH("Start_Icon_Phone.png"),
        RES_PATH("Start_Icon_SMS.png"),
        RES_PATH("Start_Icon_Msg.png")
    };
    RECT rect;

    DrawImageClass*  drawDC = new DrawImageClass();
    //init the notification area

    for ( int i=0; i < NOTI_NUM ; i++)
    {
        m_rcNotiPostion[i] = RectEx( rc.left,
                                     rc.top + ( rc.bottom - rc.top )*(3*i)/12 ,
                                     rc.right,
                                     rc.top + ( rc.bottom - rc.top )*( 3*i + 2 )/12 );
        EVALUATERECT( m_NotiRectList[i].m_rc,m_rcNotiPostion[i]);
        m_NotiRectList[i].m_NotiName = ( NOTI_NAME ) i;

        rect.bottom = m_rcNotiPostion[i].bottom - m_rcScreen.bottom / 10 ;
        rect.top = m_rcNotiPostion[i].top - m_rcScreen.bottom / 10 ;
        rect.right = m_rcNotiPostion[i].right ;
        rect.left = m_rcNotiPostion[i].left ;

        drawDC ->DrawImageToDC ( m_hMemoryDC , rect, szNotiPicture[i] );

    }
    m_CurPressedIcon = NO_NOTI;

    delete drawDC;


    //init the missed envent count
    m_MissedCallCount = m_MissedSMSCount = m_MissedEmailCount = 0;

    RegisterForPhoneNotifications();

    //set missed event
    TCHAR szBuf[50] = {'\0'};
    DWORD nBufSize = 50;
    if ( RegReadKey(SN_PHONEMISSEDCALLS_ROOT,
                    SN_PHONEMISSEDCALLS_PATH,
                    SN_PHONEMISSEDCALLS_VALUE,
                    (LPBYTE)szBuf,
                    &nBufSize)
       )
    {
        SetMissedEvent(MISSEDCALL_EVENT, szBuf[0]);
    }

    memset(szBuf, '\0', 50 * sizeof(TCHAR));
    if ( RegReadKey(SN_MESSAGINGSMSUNREAD_ROOT,
                    SN_MESSAGINGSMSUNREAD_PATH,
                    SN_MESSAGINGSMSUNREAD_VALUE,
                    (LPBYTE)szBuf,
                    &nBufSize)
       )
    {
        SetMissedEvent(MISSEDSMS_EVENT, szBuf[0]);
    }

    memset(szBuf, '\0', 50 * sizeof(TCHAR));
    if ( RegReadKey(SN_MESSAGINGTOTALEMAILUNREAD_ROOT,
                    SN_MESSAGINGTOTALEMAILUNREAD_PATH,
                    SN_MESSAGINGTOTALEMAILUNREAD_VALUE,
                    (LPBYTE)szBuf,
                    &nBufSize)
       )
    {
        SetMissedEvent(MISSEDEMAIL_EVENT, szBuf[0]);
    }

}


void HomePanel::SetMissedEvent( MISSED_EVENT me, UINT nEventCnt )
{

//	SetInconRegion( me );
    if ( m_NotiRectList[ me ].m_bIsEmpty == FALSE )
    {
        m_NotiRectList[ me ].m_bIsEmpty = TRUE;
    }

    switch (me)
    {
    case MISSEDCALL_EVENT:
        m_MissedCallCount = nEventCnt;
        break;

    case MISSEDSMS_EVENT:
        m_MissedSMSCount  = nEventCnt;

        break;
    case MISSEDEMAIL_EVENT:
        m_MissedEmailCount = nEventCnt;

        break;
    default:
        break;
    }

    return;
}

void HomePanel::SetInconRegion( MISSED_EVENT me )
{
    int count1 = 0, count2 = 0;
    if ( m_NotiRectList[me].m_bIsEmpty == TRUE )
        return ;

    for ( int i = 0; i < NOTI_NUM; i++)
    {
        if ( i < me && m_NotiRectList[i].m_bIsEmpty == TRUE )
        {
            count1++;
            count2++;
        }

        if ( i > me && m_NotiRectList[i].m_bIsEmpty == TRUE )
        {
            count2++;
            EVALUATERECT(  m_NotiRectList[i].m_rc ,m_rcNotiPostion[ count2 ]);
        }
    }
    EVALUATERECT(  m_NotiRectList[ me ].m_rc ,m_rcNotiPostion[ count1 ]);
    m_NotiRectList[ me ].m_bIsEmpty = TRUE;
    return ;
}

void HomePanel::DrawNotiIcon()
{

    for (int i = 0; i < NOTI_NUM; i++)
    {
        if ( m_NotiRectList[i].m_bIsEmpty == TRUE )
        {
            BitBlt( m_hPublicMemoryDC,
                    m_NotiRectList[i].m_rc.left ,
                    m_NotiRectList[i].m_rc.top  ,
                    m_NotiRectList[i].m_rc.right - m_NotiRectList[i].m_rc.left,
                    m_NotiRectList[i].m_rc.bottom - m_NotiRectList[i].m_rc.top,
                    m_hMemoryDC,
                    m_NotiRectList[i].m_rc.left,
                    m_NotiRectList[i].m_rc.top - m_rcScreen.bottom / 10,
                    SRCCOPY
                  );
            Logger::Instance().Log( LOG_TRACE, L"HomePanel::DrawNotiIcon: left is %d, top is %d, right is %d, bottom is %d\n",
                             m_NotiRectList[i].m_rc.left,m_NotiRectList[i].m_rc.top,
                             m_NotiRectList[i].m_rc.right,m_NotiRectList[i].m_rc.bottom);

        }
    }

    return ;
}

void HomePanel::ProcessMouseUpMenu( POINT pt)
{
    if ( m_CurPressedIcon != NO_NOTI )
    {
        BitBlt(m_hPublicMemoryDC,
               m_NotiRectList[m_CurPressedIcon].m_rc.left,
               m_NotiRectList[m_CurPressedIcon].m_rc.top,
               m_NotiRectList[m_CurPressedIcon].m_rc.right
               - m_NotiRectList[m_CurPressedIcon].m_rc.left,
               m_NotiRectList[m_CurPressedIcon].m_rc.bottom
               - m_NotiRectList[m_CurPressedIcon].m_rc.top,
               m_hMemoryDC,
               m_NotiRectList[m_CurPressedIcon].m_rc.left,
               m_NotiRectList[m_CurPressedIcon].m_rc.top - m_rcScreen.bottom / 10 ,
               SRCCOPY
              );

        DrawMemDCToCurrentDC( m_hRealDC, m_hPublicMemoryDC, m_rcScreen );
    }

    if ( PtInRect( &m_NotiRectList[m_CurPressedIcon].m_rc ,pt ) )
    {
        PROCESS_INFORMATION pi;

        switch ( m_CurPressedIcon )
        {
        case NOTI_CALL:
            PhoneShowCallLog(CALLLOGFILTER_ALL_CALLS);
            //because system doesn't update the registry in time, here we need to update
            //the registy manuelly to make sure our GUI display correctly and logically

            break;
        case NOTI_SMS:
            CreateProcess(_T("tmail.exe"),
                          _T("-service \"SMS\" -open\"inbox\""),
                          NULL, NULL, NULL,
                          0,
                          NULL, NULL, NULL,
                          &pi);

            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
            break;

        case NOTI_EMAIL:
            CreateProcess(_T("tmail.exe"),
                          NULL, NULL, NULL, NULL,
                          0,
                          NULL, NULL, NULL,
                          &pi);

            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
            break;
        default:
            break;
        }

    }
    m_CurPressedIcon = NO_NOTI;

    return ;

}

BOOL HomePanel::GetMissedEvent(void)
{
    if (m_MissedCallCount || m_MissedSMSCount || m_MissedEmailCount)
        return TRUE;
    return FALSE;
}

void HomePanel::CheckMissedEvent()
{
    Logger::Instance().Log( LOG_TRACE, L"HomePanel CheckMissedEvent() \n");
    DWORD dwBuf = 0;

    RegistryGetDWORD( SN_PHONEMISSEDCALLS_ROOT,
                      SN_PHONEMISSEDCALLS_PATH,
                      SN_PHONEMISSEDCALLS_VALUE,
                      &dwBuf);
    if ( dwBuf != 0 || m_NotiRectList[MISSEDCALL_EVENT].m_bIsEmpty == TRUE )
    {
        SetMissedEvent(MISSEDCALL_EVENT, dwBuf);
    }

    dwBuf = 0;
    RegistryGetDWORD( SN_MESSAGINGSMSUNREAD_ROOT,
                      SN_MESSAGINGSMSUNREAD_PATH,
                      SN_MESSAGINGSMSUNREAD_VALUE,
                      &dwBuf);
    if ( dwBuf != 0 || m_NotiRectList[MISSEDSMS_EVENT].m_bIsEmpty == TRUE )
    {
        SetMissedEvent(MISSEDSMS_EVENT, dwBuf);
    }

    dwBuf = 0;
    RegistryGetDWORD( SN_MESSAGINGTOTALEMAILUNREAD_ROOT,
                      SN_MESSAGINGTOTALEMAILUNREAD_PATH,
                      SN_MESSAGINGTOTALEMAILUNREAD_VALUE,
                      &dwBuf);
    if ( dwBuf != 0 || m_NotiRectList[MISSEDEMAIL_EVENT].m_bIsEmpty == TRUE )
    {
        SetMissedEvent(MISSEDEMAIL_EVENT, dwBuf);
    }
    Refresh();
}

void HomePanel::Refresh()
{
    for (int i = 0; i < NOTI_NUM; i++)
    {
        switch ( m_NotiRectList[i].m_NotiName )
        {
        case NOTI_CALL:
            if ( m_MissedCallCount == 0 )
            {
                m_NotiRectList[i].m_bIsEmpty = FALSE;
                //EMPTYRECT( m_NotiRectList[i].m_rc) ;
            }
            break;
        case NOTI_SMS:
            if ( m_MissedSMSCount == 0 )
            {
                m_NotiRectList[i].m_bIsEmpty = FALSE;
                //EMPTYRECT( m_NotiRectList[i].m_rc) ;
            }
            break;
        case NOTI_EMAIL:
            if ( m_MissedEmailCount == 0 )
            {
                m_NotiRectList[i].m_bIsEmpty = FALSE;
                //EMPTYRECT( m_NotiRectList[i].m_rc) ;
            }
            break;
        }
    }
    DrawNotiIcon();

}

void  HomePanel::CloseAllNotifications()
{
    for (int i = 0; i < NOTI_NUM; i++)
    {
        if (g_hRegNotify[i])
            RegistryCloseNotification(g_hRegNotify[i]);
    }

}

void HomePanel::SnapBackToFrame()
{}

HRESULT HomePanel::ProcessPanEnd( int nTransitionSpeed, DWORD   nTransitionAngle )
{
    return S_OK;
}

BOOL HomePanel::ProcessPan(POINTS& pt)
{
    return TRUE;
}

BOOL HomePanel::ProcessAnimationTimer()
{
    return TRUE;
}

BOOL HomePanel::RecordLastPanPoint( POINTS& pt )
{
    return TRUE;
}

BOOL HomePanel::CalculateStartPointInMemDC( POINTS& pt )
{
    return TRUE;
}

